using Sunny.UI;
using Sunny.UI.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace InsertProgramUtil
{
    public partial class NssmInsertForm : UIForm
    {
        private static readonly string[] AppPriority = new string[]{
            "REALTIME_PRIORITY_CLASS",
            "HIGH_PRIORITY_CLASS",
            "ABOVE_NORMAL_PRIORITY_CLASS",
            "NORMAL_PRIORITY_CLASS",
            "BELOW_NORMAL_PRIORITY_CLASS",
            "IDLE_PRIORITY_CLASS",
        };

        public NssmInsertForm()
        {
            InitializeComponent();

            startButton.Style = UIStyle.LayuiRed;
            regButton.Style = UIStyle.LayuiOrange;

            // 初始化运行性能选项
            foreach (var priority in AppPriority)
                performanceComboBox.Items.Add(priority);
            
            performanceComboBox.SelectedIndex = 0;
        }

        /// <summary>
        /// 选择程序位置
        /// </summary>
        private void browseButton_Click(object sender, EventArgs e)
        {
            // 打开文件选择对话框以选择程序位置
            OpenFileDialog openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                programLocationTextBox.Text = openFileDialog.FileName;
                runDirectoryTextBox.Text = Path.GetDirectoryName(openFileDialog.FileName);
            }
        }

        /// <summary>
        /// 选择运行目录
        /// </summary>
        private void selectFolderButton_Click(object sender, EventArgs e)
        {
            // 打开文件夹选择对话框以选择运行目录
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                runDirectoryTextBox.Text = folderBrowserDialog.SelectedPath;
            }
        }

        /// <summary>
        /// 启动并注册服务
        /// </summary>
        private void startButton_Click(object sender, EventArgs e)
        {
            string msg = this.reg(true);
            UIMessageDialog.ShowInfoDialog(this, msg);
        }

        /// <summary>
        /// 仅注册
        /// </summary>
        private void regButton_Click(object sender, EventArgs e)
        {
            string msg = this.reg(false);
            UIMessageDialog.ShowInfoDialog(this, msg);
        }

        /// <summary>
        /// 卸载服务
        /// </summary>
        private void uninstallButton_Click(object sender, EventArgs e)
        {
            string serverName = serverNameTextBox.Text;

            if (string.IsNullOrEmpty(serverName))
            {
                UIMessageBox.Show("请在“服务名称”栏目填写后继续");
                return;
            }

            if (UIMessageBox.ShowAsk($"你真的要卸载服务“{serverName}”吗？"))
            {
                var command = $"sc stop {serverName} & sc delete {serverName}";

                // 以管理员权限运行脚本命令
                var msg = "";
                StartProcessAsAdmin(command, (o,ev) => {
                    msg += ev.Data + "\r\n";
                });

                UIMessageBox.Show("操作成功："  + msg);
            }
        }

        #region 私有方法

        /// <summary>
        /// 注册服务
        /// </summary>
        private string reg(bool needStart)
        {
            #region 获取用户输入的内容

            string programLocation = programLocationTextBox.Text;
            if (CheckSrringIsNull(programLocation, "程序位置不可为空"))
                return null;

            string runDirectory = runDirectoryTextBox.Text;
            if (CheckSrringIsNull(runDirectory, "运行位置不可为空"))
                return null;

            string performance = AppPriority[performanceComboBox.SelectedIndex];
            if (CheckSrringIsNull(performance, "运行模式不可为空"))
                return null;

            string serverName = serverNameTextBox.Text;
            if (CheckSrringIsNull(serverName, "服务名称不可为空"))
                return null;

            string desc = serverDescTextBox.Text;
            if (CheckSrringIsNull(serverName, "服务说明不可为空"))
                return null;

            #endregion

            #region 构建脚本命令

            string command = "";

            // 进入nssm目录
            command += $"cd /d \"{Application.StartupPath}\\nssm\\Win64\" ";
            // 安装服务并指定程序文件
            command += $"& nssm install {serverName} \"{programLocation}\" ";
            // 设定程序目录
            command += $"& nssm set {serverName} AppDirectory \"{runDirectory}\" ";
            // 设定程序性能
            command += $"& nssm set {serverName} AppPriority \"{performance}\" ";
            // 设定程序备注
            command += $"& nssm set {serverName} Description \"{desc}\" ";
            // 依据情况是否立即启动
            command += needStart ? $"& nssm start {serverName}" : "";

            #endregion

            // 以管理员权限运行脚本命令
            string msg = "";
            StartProcessAsAdmin(command, (o, e) => {
                msg += e.Data + "\r\n";
            });

            return msg;
        }

        /// <summary>
        /// 以管理员身份运行服务
        /// </summary>
        private void StartProcessAsAdmin(string command, DataReceivedEventHandler e)
        {
            ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
            processStartInfo.Verb = "runas"; // 请求管理员权限
            processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            processStartInfo.RedirectStandardOutput = true;
            processStartInfo.UseShellExecute = false;
            processStartInfo.CreateNoWindow = true;

            Process process = new Process();
            process.StartInfo = processStartInfo;
            process.OutputDataReceived += e;

            process.Start();

            process.BeginOutputReadLine();

            process.WaitForExit();
        }

        #endregion
    }
}
